package com.fucking.great.context.plun;

import cn.hutool.core.util.StrUtil;
import com.fucking.great.context.util.GetMapDecorator;

import java.util.Map;
import java.util.Set;
/**
 * https://www.jianshu.com/p/92ca0bfbd52f <br/>
 *
 * 用于通过修改配置，切换系统架构，而不需要重构代码。<br/>
 * 粒度到组件级别: 可到组件级别切换,也可到全局配置,默认使用单架构的组件.<br/>
 *      以后实现的组件最好采用：<br/>
 *          门面和适配,拉齐各个架构使用级别的API.<br/>
 *      并提供以下几种的组件:<br/>
 *          单机<br/>
 *          集群<br/>
 *          soa<br/>
 *          微服务<br/>
 *          分布式架构<br/>
 *
 */
public abstract class AbstractFrameworkPlug extends BasePlug{
    /** 单机 */
    public static final String SINGLE_STRUCTURE = "Single-Structure";
    /** 集群 */
    public static final String CLUSTER_ARCHITECTURE = "Cluster-Architecture";
    /** soa */
    public static final String SERVICE_ORIENTED_ARCHITECTURE = "Service-Oriented-Architecture";
    /** 微服务 */
    public static final String MICRO_SERVICE_ARCHITECTURE = "Micro-Service-Architecture";
    /** 分布式架构 */
    public static final String DISTRIBUTED_ARCHITECTURE = "Distributed-Architecture";
    private final GetMapDecorator<String, String> prefixConfig;
    public AbstractFrameworkPlug(String prefixConfig,Set<String> importSet, Map<String, String> config) {
        super(importSet, config);
        this.prefixConfig = this.getPrefixConfig(prefixConfig);
    }

    public AbstractFrameworkPlug(String prefixConfig,Map<String, String> config, String[] importStr) {
        super(config, importStr);
        this.prefixConfig = this.getPrefixConfig(prefixConfig);
    }

    @Override
    protected void initUserPlunMap(Map<String, Object> userPlun) {
        String mode = getMode();
        switch (mode){
            case SINGLE_STRUCTURE:
                 this.singleStructure(userPlun);
            case CLUSTER_ARCHITECTURE:
                 this.clusterArchitecture(userPlun);
            case SERVICE_ORIENTED_ARCHITECTURE:  // soa
                 this.serviceOrientedArchitecture(userPlun);
            case MICRO_SERVICE_ARCHITECTURE:     // 微服务
                 this.microServiceArchitecture(userPlun);
            case DISTRIBUTED_ARCHITECTURE:     // 分布式架构
                 this.distributedArchitecture(userPlun);
            default:
                throw new Error(String.format("The current architecture mode is [%s] , No matching schema found。",mode));
        }
    }

    protected String getMode() {
        // 从插件配置获取模式
        String mode = this.prefixConfig.getStr("mode");
        // 从全局配置获取模式
        if (StrUtil.isBlank(mode)) {
            mode = this.getConfig().getStr("mode");
        }
        // 没有则默认单机,不需要配置就能用。友好的使用
        if (StrUtil.isBlank(mode)) {
            mode = SINGLE_STRUCTURE;
        }
        return mode;
    }




    protected abstract void distributedArchitecture(Map<String, Object> userPlun);

    protected abstract void microServiceArchitecture(Map<String, Object> userPlun);

    protected abstract void serviceOrientedArchitecture(Map<String, Object> userPlun);

    protected abstract void clusterArchitecture(Map<String, Object> userPlun);

    protected abstract void singleStructure(Map<String, Object> userPlun);

    public final GetMapDecorator<String, String> getPrefixConfig() {
        return prefixConfig;
    }
}
